package pers.chy.chyappointmentplatform.Service;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import pers.chy.chyappointmentplatform.Mapper.HisMapper.T_LydjMapper;
import pers.chy.chyappointmentplatform.Mapper.HisMapper.V_SqdDetailMapper;
import pers.chy.chyappointmentplatform.Mapper.HisMapper.Yjyy_PdjhMapper;
import pers.chy.chyappointmentplatform.Mapper.OaMapper.OA_V_PbMapper;
import pers.chy.chyappointmentplatform.Mapper.UsMapper.US_T_OrderMapper;
import pers.chy.chyappointmentplatform.Mapper.UsMapper.US_V_SqdDetailMapper;
import pers.chy.chyappointmentplatform.Model.NoMapping.WorkingTimeYsDTO;
import pers.chy.chyappointmentplatform.Model.NoMapping.YjztDTO;
import pers.chy.chyappointmentplatform.Model.OaModel.OA_V_PbDTO;
import pers.chy.chyappointmentplatform.Model.T_LydjExtDTO;
import pers.chy.chyappointmentplatform.Model.V_SqdDetailExtDTO;
import pers.chy.chyappointmentplatform.Model.Yjyy_PdjhDTO;

import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 报表统计服务
 */
@Service
public class StatisticService {

    @Autowired
    private V_SqdDetailMapper v_sqdDetailMapper;

    @Autowired
    private US_V_SqdDetailMapper us_v_sqdDetailMapper;

    @Autowired
    private US_T_OrderMapper us_t_orderMapper;

    @Autowired
    private OA_V_PbMapper oa_v_pbMapper;

    @Autowired
    private T_LydjMapper t_lydjMapper;

    @Autowired
    private Yjyy_PdjhMapper yjyy_pdjhMapper;

    /**
     * 获取申请单详情（报表1）
     *
     * @return
     */
    public List<V_SqdDetailExtDTO> doGetSqdDetail_bb1(Map params) {
        List<V_SqdDetailExtDTO> v_sqdDetailExtDTOList = new ArrayList<>();

        String yyrqBegin = (String) params.get("yyrqBegin");
        String yyrqEnd = (String) params.get("yyrqEnd");
        String zxks = (String) params.get("zxks");


        // 查HIS库
        Map condition = new HashMap();
        condition.put("yyrqBegin", yyrqBegin);
        condition.put("yyrqEnd", yyrqEnd);
        condition.put("zxks", zxks);
        condition.put("djztMin", 14); // 登记状态大于等于14（已传图的单子）
        v_sqdDetailExtDTOList = v_sqdDetailMapper.selectByCondition(condition);

        // 查超声库
        condition.put("HideRecord", 0); //同一条申请单，在US库study表中可能有多条记录
        List<V_SqdDetailExtDTO> us_v_sqdDetailExtDTOList = us_v_sqdDetailMapper.selectByCondition(condition);

        // 拼接两个库
        for (V_SqdDetailExtDTO item : v_sqdDetailExtDTOList) {
            String sqdh = item.getSqdh(); // 因为US库不严谨，sqdh字段存在字母，所以这里改为String类型
            // 通过申请单号，向US库查找
            V_SqdDetailExtDTO find = us_v_sqdDetailExtDTOList.stream().filter(var -> sqdh.equals(var.getSqdh())).findAny().orElse(null);

            // 拼接
            if (find != null) {
                item.setBgys(find.getBgys());
                item.setBgsj(find.getBgsj());
                item.setCtsj(find.getCtsj());
            }
        }


        return v_sqdDetailExtDTOList;
    }


    /**
     * 获取申请单详情（只统计US库）
     *
     * @return
     */
    public List<V_SqdDetailExtDTO> doGetSqdDetail_US(Map params) {
        List<V_SqdDetailExtDTO> v_sqdDetailExtDTOList = new ArrayList<>();

        String yyrqBegin = (String) params.get("gzrqBegin");
        String yyrqEnd = (String) params.get("gzrqEnd");
        String ctsjBegin = (String) params.get("gzrqBegin");
        String ctsjEnd = (String) params.get("gzrqEnd");
        String bgsjBegin = (String) params.get("gzrqBegin");
        String bgsjEnd = (String) params.get("gzrqEnd");
        String bgys = (String) params.get("bgys");
        String ksdm = (String) params.get("ksdm");
        String ztmc = (String) params.get("ztmc");


        // 查US库：指定报告日期、传图日期、报告医生、执行科室的所有申请单
        Map condition = new HashMap();
        condition.put("ctsjBegin", ctsjBegin);
        condition.put("ctsjEnd", ctsjEnd);
        condition.put("bgsjBegin", bgsjBegin);
        condition.put("bgsjEnd", bgsjEnd);
        condition.put("bgys", bgys);
        condition.put("ztmc", ztmc);
        condition.put("HideRecord", 0); //同一条申请单，在US库study表中可能有多条记录
        if ("20011".equals(ksdm)) {
            condition.put("studyDepartment_keyword", "总院"); // 暂时写死，后续改为由前端传入
        } else if ("20012".equals(ksdm)) {
            condition.put("studyDepartment_keyword", "分院");
        }
        v_sqdDetailExtDTOList = us_v_sqdDetailMapper.selectByCondition(condition);
        return v_sqdDetailExtDTOList;
    }


    /**
     * 获取医生的工作时长
     *
     * @return
     */
    public List<WorkingTimeYsDTO> doGetWorkingHors_Ys(Map params) throws Exception {
        List<WorkingTimeYsDTO> res = new ArrayList<>();

        String gzrqBegin = (String) params.get("gzrqBegin");
        String gzrqEnd = (String) params.get("gzrqEnd");
        String ksdm = (String) params.get("ksdm");


        // 查US库：指定报告日期、传图日期的所有申请单
        Map condition = new HashMap();
        condition.put("ctsjBegin", gzrqBegin);
        condition.put("ctsjEnd", gzrqEnd);
        condition.put("bgsjBegin", gzrqBegin);
        condition.put("bgsjEnd", gzrqEnd);
        condition.put("HideRecord", 0); //同一条申请单，在US库study表中可能有多条记录
        if ("20011".equals(ksdm)) {
            condition.put("studyDepartment_keyword", "总院"); // 暂时写死，后续改为由前端传入
        } else if ("20012".equals(ksdm)) {
            condition.put("studyDepartment_keyword", "分院");
        }

        List<V_SqdDetailExtDTO> us_v_sqdDetailExtDTOList = us_v_sqdDetailMapper.selectByCondition(condition);


        // 查HIS库
//        Map condition = new HashMap();
//        condition.put("yyrqBegin", gzrq);
//        condition.put("yyrqEnd", gzrq);
//        condition.put("zxks", ksdm);
//        condition.put("djztMin", 14); // 登记状态大于等于14（已传图的单子）
//        List<V_SqdDetailExtDTO> v_sqdDetailExtDTOList =v_sqdDetailMapper.selectByCondition(condition);
//
//        // 查超声库
//        condition.put("HideRecord", 0); //同一条申请单，在US库study表中可能有多条记录
//        List<V_SqdDetailExtDTO> us_v_sqdDetailExtDTOList  = us_v_sqdDetailMapper.selectByCondition(condition);
//
//        // 拼接两个库
//        for (V_SqdDetailExtDTO item: v_sqdDetailExtDTOList) {
//            String sqdh = item.getSqdh(); // 因为US库不严谨，sqdh字段存在字母，所以这里改为String类型
//            // 通过申请单号，向US库查找
//            V_SqdDetailExtDTO find = us_v_sqdDetailExtDTOList.stream().filter(var -> sqdh.equals (var.getSqdh())).findAny().orElse(null);
//
//            // 拼接
//            if(find!=null){
//                item.setBgys(find.getBgys());
//                item.setBgsj(find.getBgsj());
//                item.setCtsj(find.getCtsj());
//            }
//        }


        //
        // 分类：按报告医生分类
        //
        Map<String, List<V_SqdDetailExtDTO>> groupByBgys = new HashMap<>();
        for (V_SqdDetailExtDTO sqd : us_v_sqdDetailExtDTOList) {
            String bgys = sqd.getBgys();
            if (bgys != null) {
                // 取这个报告医生的申请单列表
                List<V_SqdDetailExtDTO> sqdListOfBgys = groupByBgys.get(bgys);
                if (sqdListOfBgys == null) {
                    groupByBgys.put(bgys, new ArrayList<>());    // 不存在则新建
                    sqdListOfBgys = groupByBgys.get(bgys);      // 新建后写入申请单
                    sqdListOfBgys.add(sqd);
                } else {
                    sqdListOfBgys.add(sqd); // 存在此医生分类，则直接追加
                }
            }
        }

        //
        // 计算：每个医生的有效工作时长、病人数量、第一个病人的传图时间、最后一个病人的报告时间
        //
        for (Map.Entry<String, List<V_SqdDetailExtDTO>> entry : groupByBgys.entrySet()) {
            String key = entry.getKey();
            List<V_SqdDetailExtDTO> value = entry.getValue();

            // 遍历这个医生的所有检查单
            long totalSecond = 0;
            Date firstCtsj = value.get(0).getCtsj();
            Date lastBgsj = value.get(0).getBgsj();
            for (V_SqdDetailExtDTO sqd : value) {
                totalSecond += sqd.getGzsj_second(); // 有效工作时长（秒数）
                if (firstCtsj.after(sqd.getCtsj()) == true) {
                    firstCtsj = sqd.getCtsj();    // 此医生的最早传图时间
                }
                if (lastBgsj.after(sqd.getBgsj()) == false) {
                    lastBgsj = sqd.getBgsj();     // 此医生的最晚报告时间
                }
            }

            long 余秒数 = totalSecond % 60;
            totalSecond -= 余秒数; // 此时totalSecond必然是一个整分钟数
            long 余分钟数 = (totalSecond / 60) % 60;
            long 整小时数 = (totalSecond / 60) / 60;

            //
            WorkingTimeYsDTO temp = new WorkingTimeYsDTO();
            temp.setBgys(key);
            temp.setWorkingHours(整小时数 + "小时" + 余分钟数 + "分钟" + 余秒数 + "秒");
            temp.setSqdsl(value.size());
            temp.setFirstCtsj(firstCtsj);
            temp.setLastBgsj(lastBgsj);
            res.add(temp);
        }


        // 连接OA库：写入医生当天排班
        if (gzrqBegin != null && gzrqBegin.equals(gzrqEnd)) {  // 暂时只计算一天范围内的排班

            // 计算是星期几
            Date gzrqDate = new SimpleDateFormat("yyyy-MM-dd").parse(gzrqBegin);
            Calendar cal = Calendar.getInstance();
            cal.setTime(gzrqDate);
            int weekDayID = cal.get(Calendar.DAY_OF_WEEK) - 1;
            if (weekDayID == 0) weekDayID = 7;

            // 查OA库：获取指定日期的医生排班表
            List<OA_V_PbDTO> oa_v_pbDTOList = oa_v_pbMapper.selectByDate("超声", gzrqEnd, weekDayID); // 暂时写死，只查超声科的排班

            for (int i = 0; i < res.size(); i++) {
                String bgys = res.get(i).getBgys();
                // 通过医生姓名，向OA库查找
                OA_V_PbDTO find = oa_v_pbDTOList.stream().filter(var -> bgys.equals(var.getNewYgxm())).findAny().orElse(null);
                if (find != null) {
                    res.get(i).setOApaiban(find.getBc());
                }
            }

        }


        return res;
    }

    /**
     * 获取医技组套数据
     *
     * @param params
     * @return
     * @throws Exception
     */
    public List<YjztDTO> doGetYjzt(Map params) throws Exception {

        List<YjztDTO> yjztDTOList = us_t_orderMapper.selectYjzt();

        return yjztDTOList;
    }


    /**
     * 获取组套的工作时长（平均用时）
     *
     * @return
     */
    public List<YjztDTO> doGetWorkingHors_Zt(Map params) throws Exception {
        List<YjztDTO> res = new ArrayList<>();

        String gzrqBegin = (String) params.get("gzrqBegin");
        String gzrqEnd = (String) params.get("gzrqEnd");
        String ksdm = (String) params.get("ksdm");
        String orderMethod = (String) params.get("orderMethod");    // 排序方式
        String ztmc = (String) params.get("ztmc");
        String[] ztmcArray = ztmc.split(",");


        // 查US库：指定报告日期、传图日期的'每个医生的医技组套的平均工作时长'
        Map condition = new HashMap();
        condition.put("ctsjBegin", gzrqBegin);
        condition.put("ctsjEnd", gzrqEnd);
        condition.put("bgsjBegin", gzrqBegin);
        condition.put("bgsjEnd", gzrqEnd);
        condition.put("HideRecord", 0); //同一条申请单，在US库study表中可能有多条记录
        condition.put("ztmc", ztmcArray);
        condition.put("orderMethod", orderMethod);
        if ("20011".equals(ksdm)) {
            condition.put("studyDepartment_keyword", "总院"); // 暂时写死，后续改为由前端传入
        } else if ("20012".equals(ksdm)) {
            condition.put("studyDepartment_keyword", "分院");
        }
        res = us_v_sqdDetailMapper.selectYjztAvgWokringTime(condition);

        return res;
    }


    /**
     * 获取'来院登记'报表
     *
     * @param params
     * @return
     * @throws Exception
     */
    public Map doGetLydj(Map params) throws Exception {
        List<T_LydjExtDTO> t_lydjExtDTOList = new ArrayList<>();
        int pageCount = 0;

        String djsjBegin = params.get("djsjBegin").toString();
        String djsjEnd = params.get("djsjEnd").toString();
        Object currentPageObj = params.get("currentPage");
        Object yqbsObj = params.get("yqbs");

        // 共同条件
        Map condition = new HashMap();
        condition.put("djsjBegin", djsjBegin);
        condition.put("djsjEnd", djsjEnd);
        if (yqbsObj != null) {
            condition.put("yqbs", Integer.parseInt(yqbsObj.toString())); // 院区标识为空时，查询全院数据
        }

        // 不分页查询
        if (currentPageObj == null) {
            t_lydjExtDTOList = t_lydjMapper.selectForStatistic(condition);
        }
        // 分页查询
        else {

            int pageNum = Integer.parseInt(currentPageObj.toString());              // 当前页数
            int pageSize = Integer.parseInt(params.get("pageSize").toString());     // 每页的记录数
            int recordNumBegin = (pageNum - 1) * pageSize + 1;
            int recordNumEnd = pageNum * pageSize;
            condition.put("recordNumBegin", recordNumBegin);
            condition.put("recordNumEnd", recordNumEnd);
            condition.put("pageSize", pageSize);
            t_lydjExtDTOList = t_lydjMapper.selectForStatistic_Page(condition);  // 分页查询
            // 计算总页数
            List<T_LydjExtDTO> tempList = t_lydjMapper.selectForStatistic(condition);
            pageCount = tempList.size() / pageSize + (tempList.size() % pageSize == 0 ? 0 : 1);
        }

        Map ret = new HashMap();
        ret.put("data", t_lydjExtDTOList);
        ret.put("pageCount", pageCount);

        return ret;
    }


    /**
     * 获取'疫苗叫号'报表
     *
     * @param params
     * @return
     * @throws Exception
     */
    public Map doGetYM(Map params) throws Exception {
        List<Yjyy_PdjhDTO> yjyy_pdjhDTOList = new ArrayList<>();
        int pageCount = 0;

        String qhrqBegin = params.get("qhrqBegin").toString();
        String qhrqEnd = params.get("qhrqEnd").toString();
        Object currentPageObj = params.get("currentPage");

        // 共同条件
        Map condition = new HashMap();
        condition.put("qhrqBegin", qhrqBegin);
        condition.put("qhrqEnd", qhrqEnd);
        condition.put("ywlx", 2);   // 写死：疫苗叫号的业务类型是2
        // 不分页查询
        if (currentPageObj == null) {
            yjyy_pdjhDTOList = yjyy_pdjhMapper.selectForStatistic(condition);
        }
        // 分页查询
        else {
            // 分页查询
            int pageNum = Integer.parseInt(currentPageObj.toString());              // 当前页数
            int pageSize = Integer.parseInt(params.get("pageSize").toString());     // 每页的记录数
            int recordNumBegin = (pageNum - 1) * pageSize + 1;
            int recordNumEnd = pageNum * pageSize;
            condition.put("recordNumBegin", recordNumBegin);
            condition.put("recordNumEnd", recordNumEnd);
            condition.put("pageSize", pageSize);
            yjyy_pdjhDTOList = yjyy_pdjhMapper.selectForStatistic_Page(condition);  // 分页查询
            // 计算总页数
            List<Yjyy_PdjhDTO> tempList = yjyy_pdjhMapper.selectForStatistic(condition);
            pageCount = tempList.size() / pageSize + (tempList.size() % pageSize == 0 ? 0 : 1);
        }

        Map ret = new HashMap();
        ret.put("data", yjyy_pdjhDTOList);
        ret.put("pageCount", pageCount);

        return ret;
    }


}
